/*
 * Copyright 2016-2018 TVI Go Easy.
 * Created on 2018/1/23 17:02
 */
package com.tvi.cloud.license.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.tvi.cloud.license.model.License;
import com.tvi.cloud.license.repository.LicenseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 许可服务
 *
 * @author mechanic
 */
@Service
//类级别的 Hystrix 属性
//@DefaultProperties()
public class LicenseService {

    private final LicenseRepository licenseRepository;

    @Autowired
    public LicenseService(LicenseRepository licenseRepository) {
        this.licenseRepository = licenseRepository;
    }

    /**
     * 按许可ID查找许可新消息
     *
     * @param id 许可ID
     * @return 许可信息
     */
    public License findOne(String id) {
        return this.licenseRepository.findOne(id);
    }

    /**
     * 保存(新增或更新)许可信息
     *
     * @param license 许可信息
     * @return 保存后的许可信息
     */
    public License save(License license) {
        return this.licenseRepository.save(license);
    }

    /**
     * 按许可ID删除许可信息
     *
     * @param id 许可ID
     */
    public void delete(String id) {
        this.licenseRepository.delete(id);
    }


    /**
     * 按组织ID查抄许可信息
     *
     * @param organizationId 组织ID
     * @return 许可信息
     */
    //方法级别的 Hystrix 属性
    @HystrixCommand(
            //回退。如果该方法调用失败，将会回退并调用 buildFallbackLicenseList(String) 方法，
            //被调用的方法需与本方法在同一个类中，并且签名需要一致。
            fallbackMethod = "buildFallbackLicenseList",
            //独立的线程池名称
            threadPoolKey = "licenseByOrgThreadPool",
            //线程池属性
            threadPoolProperties = {
                    //线程池大小
                    @HystrixProperty(name = "coreSize", value = "30"),
                    //线程池队列大小
                    @HystrixProperty(name = "maxQueueSize", value = "10")},
            commandProperties = {
                    //设置断路超时时间，默认为1000毫秒
                    //@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
                    //Hystrix 监控窗口周期。此值的默认值是 10000 毫秒（即 10 秒）
                    //10-second window
                    @HystrixProperty(name="metrics.rollingStats.timeInMilliseconds", value="15000"),
                    //控制你在窗口中定义并被收集的统计次数
                    @HystrixProperty(name="metrics.rollingStats.numBuckets", value="5"),
                    //连续调用数量。在 metrics.rollingStats.timeInMilliseconds 的窗口内必须出现的连续调用数量
                    @HystrixProperty(name="circuitBreaker.requestVolumeThreshold", value="10"),
                    //失败比例。在断路器跳闸之前 circuitBreaker.requestVolumeThreshold 失败的百分比（由于超时，将抛出一个异常，或返回 HTTP 500）。
                    @HystrixProperty(name="circuitBreaker.errorThresholdPercentage", value="70"),
                    //断路器跳闸后的休眠时间。休眠过后开始尝试是否恢复
                    @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds", value="7000"),
            })
    public List<License> getLicenseList(String organizationId) {
        try {
            Thread.sleep(1100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return this.licenseRepository.findByOrganizationId(organizationId);
    }

    public List<License> buildFallbackLicenseList(String organizationId) {
        License license = new License(organizationId, "3", "fallback product name", "fallback license type");
        List<License> licenseList = new ArrayList<>();
        licenseList.add(license);
        return licenseList;
    }
}
